﻿using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Web;

namespace HomeService.Models
{
    public class ServiceRequestPhoto
    {
        public ServiceRequestPhoto() {}

        public ServiceRequestPhoto(HttpPostedFileBase imageFile, string description)
        {
            var image = ValidateAndGetImage(imageFile);

            Id = Guid.NewGuid().ToString();
            Image = ResizeImage(image, 600, 600);
            MimeType = imageFile.ContentType;
            Description = description;
        }

        public string Id { get; private set; }
        public Image Image { get; private set; }
        public string MimeType { get; private set; }

        [DisplayName("Kuvaus"), DataType(DataType.MultilineText)]
        public string Description { get; set; }

        /// <summary>
        /// Gets the image data as a byte array.
        /// </summary>
        public byte[] Bytes
        {
            get
            {
                var stream = new MemoryStream();
                Image.Save(stream, ImageFormat.Jpeg); // TODO
                return stream.ToArray();
            }
        }

        private static Image ResizeImage(Image image, int? maxWidth, int? maxHeight)
        {
            // Get max width and height
            var maxWidthValue = maxWidth ?? image.Width;
            var maxHeightValue = maxHeight ?? image.Height;

            // Check if no resizing is neccessary
            if (image.Height < maxHeightValue && image.Width < maxWidthValue) return image;

            // Calculate mew width and height 
            var widthRatio = (double) image.Width / maxWidthValue;
            var heightRatio = (double) image.Height / maxHeightValue;
            var ratio = Math.Max(widthRatio, heightRatio);
            var newWidth = (int) Math.Floor(image.Width / ratio);
            var newHeight = (int) Math.Floor(image.Height / ratio);

            // Create and return resized image
            var resizedImage = new Bitmap(newWidth, newHeight);
            using (var graphics = Graphics.FromImage(resizedImage))
            {
                graphics.SmoothingMode = SmoothingMode.AntiAlias;
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                graphics.DrawImage(image, new Rectangle(0, 0, newWidth, newHeight));
            }
            image.Dispose();
            return resizedImage;
        }

        private static Image ValidateAndGetImage(HttpPostedFileBase imageFile)
        {
            Image image = null;
            var validationException = new ValidationException<ServiceRequestPhoto>();
            const string errorMessage = "Tiedoston täytyy olla JPEG- tai PNG-kuva.";
            if (imageFile != null) {
                try {
                    image = new Bitmap(imageFile.InputStream);
                    if (!(image.RawFormat.Equals(ImageFormat.Jpeg) || image.RawFormat.Equals(ImageFormat.Png)))
                        validationException.AddErrorForModel(errorMessage);
                } catch {
                    validationException.AddErrorForModel(errorMessage);
                }
            } else {
                validationException.AddErrorForModel("Tiedosto ei voi olla tyhjä.");
            }
            validationException.ThrowIfErrors();
            return image;
        }
    }
}